{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "646f4486",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 自动求导\n",
    "import torch\n",
    "\n",
    "x = torch.arange(4.0)\n",
    "x.requires_grad_(True)\n",
    "x.grad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "a1ad78b7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor(28., grad_fn=<MulBackward0>)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = 2 * torch.dot(x, x)# y是标量\n",
    "y # 求梯度的函数grad_fn=<MulBackward0> 表示y是从x计算过来的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "a5ac56e2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([ 0.,  4.,  8., 12.])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.backward()# 反向传播,求导\n",
    "x.grad # 导数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "38df23bd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([True, True, True, True])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.grad == 4 * x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "323b3e7b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([1., 1., 1., 1.])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 在默认情况下，Pytorch会累积梯度，我们需要清除之前的值\n",
    "x.grad.zero_()# 下划线表示重写内容，梯度清零\n",
    "y = x.sum()# 向量的sum，梯度为全1\n",
    "y.backward()\n",
    "x.grad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "183c4ad7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([2., 2., 2., 2.])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 在默认情况下，Pytorch会累积梯度，我们需要清除之前的值\n",
    "#x.grad.zero_()# 下划线表示重写内容，梯度清零\n",
    "y = x.sum()# 向量的sum，梯度为全1\n",
    "y.backward()\n",
    "x.grad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "78ddd646",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([3., 3., 3., 3.])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 在默认情况下，Pytorch会累积梯度，我们需要清除之前的值\n",
    "#x.grad.zero_()# 下划线表示重写内容，梯度清零\n",
    "y = x.sum()# 向量的sum，梯度为全1\n",
    "y.backward()\n",
    "x.grad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "14bb0ba9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([0., 2., 4., 6.])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# y为非标量\n",
    "\n",
    "x.grad.zero_()\n",
    "y = x * x # y为矩阵\n",
    "\n",
    "# 等价于y.backward(torch.ones(len(x)))\n",
    "y.sum().backward() # y求和，变为标量\n",
    "x.grad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "50458ebc",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
